from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, func
from typing import Optional
from app.db.database import get_db
from app.core.security import check_admin_permission, get_current_user
from app.core.exceptions import DataNotFoundError, DuplicatePublishError
from app.models.post import Announcement
from app.schemas.post import AnnouncementCreate, Announcement as AnnouncementSchema, PostList
from app.schemas.user import TokenData
from app.utils.wechat import get_wechat_article
from math import ceil

router = APIRouter(prefix="/post/announcement", tags=["公告"])

@router.get("", response_model=PostList)
async def get_announcements(
    page: int = Query(1, gt=0),
    size: int = Query(10, gt=0),
    db: AsyncSession = Depends(get_db)
):
    # 获取总数
    total = await db.scalar(select(func.count()).select_from(Announcement))
    
    # 获取分页数据
    result = await db.execute(
        select(Announcement)
        .order_by(Announcement.published_time.desc())
        .offset((page - 1) * size)
        .limit(size)
    )
    announcements = result.scalars().all()
    
    return PostList(
        total_page=ceil(total / size),
        current_page=page,
        has_next=page * size < total,
        data=announcements
    )

@router.post("/create", status_code=201)
async def create_announcement(
    announcement: AnnouncementCreate,
    current_user: TokenData = Depends(check_admin_permission),
    db: AsyncSession = Depends(get_db)
):
    # 检查是否已存在同名公告
    result = await db.execute(
        select(Announcement).where(Announcement.name == announcement.name)
    )
    if result.scalar_one_or_none():
        raise DuplicatePublishError()
    
    # 获取微信文章内容
    content = await get_wechat_article(announcement.content_url)
    
    db_announcement = Announcement(
        **announcement.dict(exclude={'content_url'}),
        content=content,
        publisher_id=current_user.id
    )
    
    db.add(db_announcement)
    await db.commit()
    
    return {"code": 10000, "data": "success"}

@router.get("/{announcement_id}/detail", response_model=AnnouncementSchema)
async def get_announcement_detail(
    announcement_id: int,
    db: AsyncSession = Depends(get_db)
):
    result = await db.execute(
        select(Announcement).where(Announcement.id == announcement_id)
    )
    announcement = result.scalar_one_or_none()
    
    if not announcement:
        raise DataNotFoundError()
    
    return announcement

@router.get("/{announcement_id}/content")
async def get_announcement_content(
    announcement_id: int,
    db: AsyncSession = Depends(get_db)
):
    result = await db.execute(
        select(Announcement.content).where(Announcement.id == announcement_id)
    )
    content = result.scalar_one_or_none()
    
    if not content:
        raise DataNotFoundError()
    
    return {"code": 10000, "data": content}

@router.get("/{announcement_id}/poster")
async def get_announcement_poster(
    announcement_id: int,
    db: AsyncSession = Depends(get_db)
):
    result = await db.execute(
        select(Announcement.poster).where(Announcement.id == announcement_id)
    )
    poster = result.scalar_one_or_none()
    
    if not poster:
        raise DataNotFoundError()
    
    return {"code": 10000, "data": poster} 